/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GUIUtilities;

import SocialMatrixPackage.SocialMatrix;
import ccpv.NamedArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import multiarray.MultiArray;
import multiarray.RecursiveAccess;

/**
 *
 * @author Evan
 */
public abstract class CoalitionUtilities
{

  public static void loadCoaltionIntoTree(JTree loadTree, SocialMatrix sm, List<int[]> coalition)
  {
    // first make sure the load tree has the same ascriptives as the sm tree
    TreeUtilities.cloneTree(sm.getAscriptiveTree(), loadTree, false);

    // now load values
    // first check what's seen
    Vector<Vector<Integer>> seen = new Vector<Vector<Integer>>();
    for (int i = 0; i < sm.getAscriptiveCategories().size(); i++)
    {
      seen.add(new Vector<Integer>());
    }

    for (int[] group : coalition)
    {
      for (int i = 0; i < group.length; i++)
      {
        Vector<Integer> ascriptiveSeen = seen.get(i);
        if (!ascriptiveSeen.contains(group[i]))
        {
          ascriptiveSeen.add(group[i]);
        }
      }
    }

    // now start to load values.
    Vector<Vector<String>> ascriptiveNames = sm.getStringNames();
    // note: does not take into account hierarchy
    for (int i = 0; i < ascriptiveNames.size(); i++)
    {
      Vector<String> ascriptiveMembers = ascriptiveNames.get(i);
      DefaultMutableTreeNode parent = TreeUtilities.findAscriptiveCategory(sm.getAscriptiveTree(), ascriptiveMembers.get(0));
      for (String s : ascriptiveMembers)
      {
        parent.add(new DefaultMutableTreeNode(s));
      }
    }

    loadTree.updateUI();
  }

  public static String getCoalitionString(List<int[]> coalitionMembers, SocialMatrix matrix)
  {
    String ret = "";

    Vector<CoalitionSet> coalitionGroups = condensedFormatHelper(coalitionMembers, matrix.getDimensions());
    for (int i = 0; i < coalitionGroups.size(); i++)
    {
      CoalitionSet cs = coalitionGroups.get(i);
      Vector<Integer> csGroups = cs.crossSections;
      if (csGroups.size() != 0)
      {
        String csString = "";
        // insert the group type
        csString += matrix.getAscriptiveCategories().get(i) + ": ";

        if (cs.isPartOfCoalition)
        {
          csString += "(";
        }
        else
        {
          csString += "NOT(";
        }

        for (int j = 0; j < csGroups.size() - 1; j++)
        {
          csString += matrix.getStringNames().get(i).get(csGroups.get(j)) + ", ";
        }
        csString += matrix.getStringNames().get(i).get(csGroups.get(csGroups.size() - 1));
        csString += ")";
        ret += csString + "\n";
      }
    }

    return ret;
  }

  public static String getCoalitionStringAsInts(List<int[]> coalitionMembers)
  {
    String ret = "";

    for (int[] array : coalitionMembers)
    {
      ret += "[";
      for (int i = 0; i < array.length - 1; i++)
      {
        ret += array[i] + ", ";
      }
      ret += array[array.length - 1] + "]\n";
    }

    return ret;
  }

  // forms a vector of coalitionsets... these represent which groups are in the coalition for every
  // ascriptive type.  Therefore, if there are n dimensions, there will be n members in the return
  // vector.
  public static Vector<CoalitionSet> condensedFormatHelper(List<int[]> coalitionMembers, int[] dimensions)
  {
    Vector<Vector<Integer>> seen = new Vector<Vector<Integer>>();
    // setup default seen vectors
    int[] sample = coalitionMembers.get(0);
    for (int i = 0; i < sample.length; i++)
    {
      seen.add(new Vector<Integer>());
    }

    for (int i = 0; i < coalitionMembers.size(); i++)
    {
      int[] crossSection = coalitionMembers.get(i);

      for (int j = 0; j < crossSection.length; j++)
      {
        Integer crossSectionAscriptive = crossSection[j];
        if (!seen.get(j).contains(crossSectionAscriptive))
        {
          seen.get(j).add(crossSectionAscriptive);
        }
      }
    }

    // now that we know what's seen, let's see which need "not" prefixes
    Vector<CoalitionSet> ret = new Vector<CoalitionSet>();
    for (int i = 0; i < seen.size(); i++)
    {
      Vector<Integer> seenAscriptive = seen.get(i);
      CoalitionSet cs;
      System.out.println("seen: " + seenAscriptive.size());
      System.out.println("dim: " + dimensions[i]);
      if (seenAscriptive.size() < (dimensions[i] / 2))
      {
        cs = new CoalitionSet(seenAscriptive, true);
      }
      else
      {
        System.out.println("called");
        Vector<Integer> notV = new Vector<Integer>();
        for (int j = 0; j < dimensions[i]; j++)
        {
          if (!seenAscriptive.contains(j))
          {
            notV.add(j);
          }
        }
        cs = new CoalitionSet(notV, false);
      }
      ret.add(cs);
    }

    return ret;
  }

  public static JTree getAscriptiveTree(List<NamedArrayList<String>> ascriptives)
  {
    JTree ascriptiveTree = new JTree();

    // all the roots
    DefaultMutableTreeNode tree1Root = (DefaultMutableTreeNode) ascriptiveTree.getModel().getRoot();
    tree1Root.removeAllChildren();

    // iterate through the ascriptive categories
    for (int i = 0; i < ascriptives.size(); i++)
    {
      NamedArrayList<String> ascriptiveCategory = ascriptives.get(i);

      DefaultMutableTreeNode ascriptiveCategoryNode1 = new DefaultMutableTreeNode(ascriptiveCategory.name);

      for (int j = 0; j < ascriptiveCategory.size(); j++)
      {
        String categoryEntry = ascriptiveCategory.get(j);

        DefaultMutableTreeNode categoryEntryNode1 = new DefaultMutableTreeNode(categoryEntry);
        ascriptiveCategoryNode1.add(categoryEntryNode1);
      }

      tree1Root.add(ascriptiveCategoryNode1);
    }

    ascriptiveTree.updateUI();

    return ascriptiveTree;
  }

  public static String getPartitionString(List<List<int[]>> partition)
  {
    String print = "";

    for (int j = 0; j < partition.size(); j++)
    {
      List<int[]> coalition = partition.get(j);
      print += "Coalition: " + j + "\n";
      for (int k = 0; k < coalition.size(); k++)
      {
        int[] group = coalition.get(k);
        String groupS = "[";
        for (int l = 0; l < group.length - 1; l++)
        {
          groupS += group[l] + ", ";
        }
        groupS += group[group.length - 1] + "]";

        print += groupS + "\n";
      }
    }

    return print;
  }

  public static String getPartitionsString(List<List<List<int[]>>> partitions)
  {
    String print = "";

    for (int i = 0; i < partitions.size(); i++)
    {
      print += "Partition: " + i + "\n";
      List<List<int[]>> partition = partitions.get(i);

      for (int j = 0; j < partition.size(); j++)
      {
        List<int[]> coalition = partition.get(j);
        print += "Coalition: " + j + "\n";
        for (int k = 0; k < coalition.size(); k++)
        {
          int[] group = coalition.get(k);
          String groupS = "[";
          for (int l = 0; l < group.length - 1; l++)
          {
            groupS += group[l] + ", ";
          }
          groupS += group[group.length - 1] + "]";

          print += groupS + "\n";
        }
      }

    }

    return print;
  }

  public static String getAltruismAsFloatsPrintString(MultiArray<MultiArray<Float>> altruisms)
  {
    String ret = "";

    List<int[]> allCombos = RecursiveAccess.generateAllPermutations(altruisms.getDimensions());
    for (int[] source : allCombos)
    {
      MultiArray<Float> feelings = altruisms.getElementAtIndex(source);
      for (int[] target : allCombos)
      {
        float value = feelings.getElementAtIndex(target);
        ret += ListUtilities.getIntArrayString(source) + " --> " + ListUtilities.getIntArrayString(target) + ": " + value + "\n";
      }
    }

    return ret;
  }

  public static String getAltruismAsDoublesPrintString(MultiArray<MultiArray<Double>> altruisms)
  {
    String ret = "";

    List<int[]> allCombos = RecursiveAccess.generateAllPermutations(altruisms.getDimensions());
    for (int[] source : allCombos)
    {
      MultiArray<Double> feelings = altruisms.getElementAtIndex(source);
      for (int[] target : allCombos)
      {
        double value = feelings.getElementAtIndex(target);
        ret += ListUtilities.getIntArrayString(source) + " --> " + ListUtilities.getIntArrayString(target) + ": " + value + "\n";
      }
    }

    return ret;
  }
}
